﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.Core.Presentation;
using ICSharpCode.Core;
using System.Windows.Input;
using System.Reflection;

namespace MyWPFWorkBench.FluentRibbon
{
    /// <summary>
    /// Creates WPF ribbon controls from the AddIn Tree.
    /// </summary>
    public static class FluentRibbonService
    {
        internal sealed class RibbonCreateContext
        {
            public UIElement InputBindingOwner;
            public string ActivationMethod;
        }
        public static void UpdateStatus(IEnumerable ribbonItems)
        {
            if (ribbonItems == null)
                return;
            foreach (object o in ribbonItems)
            {
                IStatusUpdate cmi = o as IStatusUpdate;
                if (cmi != null)
                    cmi.UpdateStatus();
                if (o is RibbonTabItem)
                {
                    UpdateStatus(((RibbonTabItem)o).Groups);
                }
                if (o is RibbonGroupBox)
                {
                    UpdateStatus(((RibbonGroupBox)o).ItemsSource);
                }
            }
        }

        public static void UpdateText(IEnumerable ribbonItems)
        {
            if (ribbonItems == null)
                return;
            foreach (object o in ribbonItems)
            {
                IStatusUpdate cmi = o as IStatusUpdate;
                if (cmi != null)
                    cmi.UpdateText();
            }
        }

        public static IList CreateRibbonItems(UIElement inputBindingOwner, object owner, string addInTreePath, string activationMethod = null)
        {
            return CreateRibbonSubItems(
                new RibbonCreateContext
                {
                    InputBindingOwner = inputBindingOwner,
                    ActivationMethod = activationMethod
                },
                AddInTree.BuildItems<RibbonItemDescriptor>(addInTreePath, owner, false));
            
        }
        internal static IList CreateRibbonSubItems(RibbonCreateContext context, IEnumerable descriptors)
        {
            ArrayList result = new ArrayList();
            if (descriptors != null)
            {
                foreach (RibbonItemDescriptor descriptor in descriptors)
                {
                    result.Add(CreateRibbonItemFromDescriptor(context, descriptor));
                }
            }
            return result;
        }
        
        static object CreateRibbonItemFromDescriptor(RibbonCreateContext context, RibbonItemDescriptor descriptor)
        {
            Codon codon = descriptor.Codon;
            string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Command";
            bool createCommand = codon.Properties["loadclasslazy"] == "false";

            switch (type)
            {
                case "Separator":
                    return new Separator();
                
                case "Item":
                case "Command":
                    return new RibbonButton(context.InputBindingOwner, codon, descriptor.Caller, createCommand, descriptor.Conditions);//context.ActivationMethod,
                case "Tab":
                    var tabItem = new RibbonTabItem(codon, descriptor.Caller, descriptor.Conditions);

                    var subItems = CreateRibbonSubItems(context, descriptor.SubItems);
                    foreach (RibbonGroupBox gb in subItems)
                    {
                        tabItem.Groups.Add(gb);
                    }

                    return tabItem;
                case "Group":
                    var groupItem = new RibbonGroupBox(codon, descriptor.Caller, descriptor.Conditions);

                    groupItem.ItemsSource = CreateRibbonSubItems(context, descriptor.SubItems);


                    return groupItem;
                
                default:
                    throw new NotSupportedException("unsupported menu item type : " + type);
            }
        }

        /// <summary>
        /// Converts from the Windows-Forms style label format (accessor key marked with '&amp;')
        /// to a WPF label format (accessor key marked with '_').
        /// </summary>
        public static string ConvertLabel(string label)
        {
            return label.Replace("_", "__").Replace("&", "_");
        }


        /// <summary>
        /// Creates an KeyGesture for a shortcut.
        /// </summary>
        public static KeyGesture ParseShortcut(string text)
        {
            return (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(text.Replace(',', '+').Replace('|', '+'));
        }

        
    }
}
